/*
 *	spectrogram.c
 *
 *	sglib.lib
 *
 *	Audio Finger Print project
 */

#include <stdio.h>
#include <string.h>
#include "spectrogram.h"

#define RANGES 1

#if RANGES
static const float ranges[SG_MAX+1] = // 200..2000 / 3
{
	200/4000.0f,
	800/4000.0f,
	1400/4000.0f,
	2000/4000.0f, // H(3) H6
	4000/4000.0f
};
#endif

void resetSpectrogram(SPECTROGRAM* data)
{
	memset(data, 0, sizeof(SPECTROGRAM));
}

void runSpectrogram(SPECTROGRAM* data, float* bufProc)
{
	int i, j, i1, i2, idx;
	float powerPeak;

	data->powerAbsPeak = 0;

	// calculate signal power (mSpectrogram)
	for(i = 0; i < SG_FFT_SIZE2; ++i)
	{
		float re = bufProc[i*2];
		float im = bufProc[i*2+1];
		data->mSpectrogram[i] = re*re + im*im;
		if(data->mSpectrogram[i] > data->powerAbsPeak)
		{
			data->powerAbsPeak = data->mSpectrogram[i];
		}
	}
	data->powerAbsPeak *= 0.25f;

	// find maximum amplitude in each range
	for(j = 0; j < SG_MAX; ++j)
	{
		data->mBin[j] = -1;
		powerPeak = -1; // min (impossible) value

#if RANGES
		i1 = (int)(ranges[j]*SG_FFT_SIZE2);
		i2 = (int)(ranges[j+1]*SG_FFT_SIZE2);
#else
		i1 = j*SG_FFT_SIZE2/SG_MAX;
		i2 = (j+1)*SG_FFT_SIZE2/SG_MAX;
#endif
		for(i = i1; i < i2; ++i)
		{
			if((data->mSpectrogram[i] > powerPeak) && (data->mSpectrogram[i] > data->powerAbsPeak))
//			if(data->mSpectrogram[i] > powerPeak)
			{
				powerPeak = data->mSpectrogram[i];

				data->mBin[j] = i-i1;
				data->mRe[j] = bufProc[i*2];
				data->mIm[j] = bufProc[i*2+1];
			}
		}
	}

#if 1
	// zeroing
	for(i = 0; i < SG_FFT_SIZE2; ++i)
	{
		bufProc[i*2] = 0;
		bufProc[i*2+1] = 0;
	}

	// signal reconstruction using mBin, mRe and mIm data
	for(j = 0; j < SG_MAX; ++j)
	{
		if(255 != data->mBin[j])
		{
#if RANGES
			i1 = (int)(ranges[j]*SG_FFT_SIZE2);
#else
			i1 = j*SG_FFT_SIZE2/SG_MAX;
#endif
			idx = data->mBin[j]+i1;

			bufProc[idx*2  ] = data->mRe[j];
			bufProc[idx*2+1] = data->mIm[j];
		}
	}
#endif
}
